<?php

/**
 * This is the model class for table "{{article}}".
 *
 * The followings are the available columns in table '{{article}}':
 * @property integer $id
 * @property integer $parent_id
 * @property integer $account_id
 * @property string $category_id
 * @property string $user_access
 * @property integer $type_code
 * @property string $section_code
 * @property integer $layout_code
 * @property string $external_url
 * @property integer $is_new_window
 * @property string $button_css_class
 * @property integer $position
 * @property integer $total_view
 * @property integer $total_like
 * @property integer $total_comment
 * @property integer $status_code
 * @property string $create_timezone
 * @property string $create_timestamp
 * @property string $create_datetime
 * @property string $create_date
 * @property string $create_time
 * @property integer $create_by
 * @property string $update_timezone
 * @property string $update_timestamp
 * @property string $update_datetime
 * @property string $update_date
 * @property string $update_time
 * @property integer $update_by
 */
class Article extends AccountRecord {

    //filter
    public $title_;
    
    public $parent_;
    public $accountId_;
    public $categoryId_;
    public $userAccess_;
    public $type_;
    public $section_;
    public $layout_;
    public $url_;
    public $newWindow_;
    public $buttonCssClass_;
    
    public $position_;
    public $status_;
    
    private $_jsonFile;
    
    /**
     * @return string the associated database table name
     */
    public function tableName() {
        return '{{article}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('parent_, accountId_, type_, url_, buttonCssClass_, status_', 'filter', 'filter'=>'trim'),
            
            array('type_', 'in', 'range'=>array_keys($this->typeOption), 'allowEmpty'=>false),
            array('section_', 'ext.validators.ArrayValueValidator', 'range'=>array_keys($this->sectionOption), 'allowEmpty'=>false),
            array('layout_', 'in', 'range'=>array_keys($this->layoutOption), 'allowEmpty'=>false),
            
            array('url_', 'url', 'defaultScheme'=>'http'),
            array('buttonCssClass_', 'length', 'max'=>45),
            array('id_, parent_, accountId_, categoryId_, userAccess_, type_, section_, layout_, url_, newWindow_, buttonCssClass_, position_, status_', 'safe', 'on'=>'adminSearch, adminCreate, adminUpdate'),
            
            // must include
            array('status_', 'in', 'range'=>array_keys($this->statusOption), 'allowEmpty'=>false),
            
            array('var_', 'ext.validators.BotDetectionValidator'),
            array('var_', 'safe'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            // must include
            'creator' => array(self::BELONGS_TO, 'User', 'create_by'),
            'editor' => array(self::BELONGS_TO, 'User', 'update_by'),
            
            //custom
            'account'=> array(self::BELONGS_TO, 'Account', 'account_id', 'scopes'=>array('accessible')),
            'photo' => array(self::HAS_ONE, 'Gallery', 'module_id', 'scopes' => array('module' => __CLASS__, 'primary')),
            'gallery' => array(self::HAS_MANY, 'Gallery', 'module_id', 'scopes' => array('module' => __CLASS__, 'ordered')),
            'html' => array(self::HAS_ONE, 'Content', 'module_id', 'scopes' => array('module' => __CLASS__, 'language' => $this->defaultLanguage)),
            'defaultHtml' => array(self::HAS_ONE, 'Content', 'module_id', 'scopes' => array('module' => __CLASS__, 'language' => $this->defaultLanguage)),
            'like'=>array(self::HAS_MANY, 'Like', 'module_id', 'scopes'=>array('module'=>__CLASS__, 'accessible')),
            'comment'=>array(self::HAS_MANY, 'Comment', 'module_id', 'scopes'=>array('module'=>__CLASS__, 'accessible', 'ordered')),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
        return array(
            'id_' => Lang::t('article.lbl.id'),
            'parent_'=>Lang::t('article.lbl.parent'),
            'accountId_' => Lang::t('article.lbl.account'),
            'categoryId_' => Lang::t('article.lbl.category'),
            'type_' => Lang::t('article.lbl.type'),
            'section_' => Lang::t('article.lbl.section'),
            'url_' => Lang::t('article.lbl.url'),
            'buttonCssClass'=>Lang::t('article.lbl.button.css.class'),
            'position_' => Lang::t('article.lbl.position'),
            'status_' => Lang::t('article.lbl.status'),
        );
    }

    public function scopes() {
        $t=$this->getTableAlias(false);
        return array(
            'published' => array(
                'condition' => implode(' OR ', array(
                    $t.'.status_code = :activeStatus'.$t,
                    //$t.'.status_code = :expiredStatus'.$t,
                )),
                'params' => array(
                    ':activeStatus'.$t => Option::STATUS_ACTIVE,
                    //':expiredStatus'.$t => Option::STATUS_EXPIRED,
                ),
            ),
            'accessible'=>array(
                'condition' => $t.'.status_code <> :deletedStatus'.$t,
                'params' => array(
                    ':deletedStatus'.$t=>Option::STATUS_DELETED,
                ),
            ),
        );
    }
    
    public function byType($type = null) {
        $t = $this->getTableAlias(false);
        $this->getDbCriteria()->mergeWith(array(
            'condition' => $t . '.type_code=:type',
            'params' => array(
                ':type' => $type,
            ),
        ));
        return $this;
    }
    
    public function autoFill(){
        switch($this->scenario){
            case 'adminCreate':
            case 'userCreate':
                $this->userAccess_=array_keys($this->userRoleOption);
                $this->section_=array_keys($this->sectionOption);
                $this->type_=Option::ARTICLE_TYPE_NORMAL;
                $this->layout_=Option::LAYOUT_2_COLUMNS;
                break;
            case 'adminUpdate':
            case 'userUpdate':
                $this->parent_=$this->parent_id;
                $this->accountId_=$this->account_id;
                $this->categoryId_=array_filter(explode(',',$this->category_id));
                $this->userAccess_=array_filter(explode(',',$this->user_access));
                $this->type_=$this->type_code;
                $this->section_=array_filter(explode(',',$this->section_code));
                $this->layout_=empty($this->layout_code)? Option::LAYOUT_2_COLUMNS:$this->layout_code;
                $this->url_=$this->external_url;
                $this->newWindow_=$this->is_new_window;
                $this->buttonCssClass_=$this->button_css_class;
                $this->status_=$this->status_code;
                break;
        }
    }    
    
    protected function afterSave() {
        parent::afterSave();
        $this->updatePosition();
    }

    public function getStatusOption($id=null){
        $option = array_intersect_key(Option::recordStatus(), array(
            Option::STATUS_ACTIVE => '',
            Option::STATUS_ARCHIVED=>'',
            Option::STATUS_SUSPENDED=>'',
        ));
        if($id===null) return $option; return isset($option[$id])? $option[$id]:null;
    }
    
    public function getParentOption($parent=0, $lvl=0){        
        $options = array();
        $criteria = new CDbCriteria;
        $criteria->compare('parent_id', $parent);
        $criteria->order='position ASC';
        if (!$this->isNewRecord) {
            $criteria->addCondition('id <> '.$this->id);
        }
        $models = $this->accessible()->findAll($criteria);
        $prefix=str_repeat('> ',$lvl++);
        foreach ($models as $data) {
            $options[$data->id] = $prefix.$data->title;
            $options+=$this->getParentOption($data->id,$lvl);
        }
        return $options;
    }
    
    public function getTypeOption($id=null){
        $option= Option::articleType();
        unset($option[Option::ARTICLE_TYPE_EVENT]
               //$option[Option::ARTICLE_TYPE_NEWS]
        );
        if($id===null) return $option; return isset($option[$id])? $option[$id]:null;
    }
    
    public function getLayoutOption($id=null){
        return Option::layoutType($id);
    }
    
    public function getCategoryOption($id=null){
        return array();
    }
    
    public function getUserRoleOption($id=null){
        return Option::userRole($id);
    }
    
    public function getSectionOption($id=null){
        $option = Option::sectionType();
        unset($option[Option::SECTION_HEADER], $option[Option::SECTION_HEADER_SCRIPT], $option[Option::SECTION_BODY_SCRIPT], $option[Option::SECTION_FOOTER_SCRIPT], $option[Option::SECTION_FOOTER]);
        if($id===null) return $option; return isset($option[$id])? $option[$id]:null;
    }
    
    protected function beforeSave(){
        if(parent::beforeSave()){
            
            if(in_array($this->scenario, array('adminUpdate'))){
                if(empty($this->parent_)) $this->parent_=0;
                if($this->parent_id!=$this->parent_){
                    $this->oldParent_=$this->parent_id;
                    $this->oldPosition_=$this->position;
                    $this->position=0;
                }
            }
            
            if(in_array($this->scenario, array('adminCreate','adminUpdate'))){
                $this->parent_id=empty($this->parent_)?0:$this->parent_;
                $this->account_id=$this->accountId_;
                $this->category_id=is_array($this->categoryId_)? implode(',',$this->categoryId_): $this->categoryId_;
                $this->user_access=is_array($this->userAccess_)? implode(',',$this->userAccess_): $this->userAccess_;
                $this->type_code=$this->type_;
                $this->section_code=is_array($this->section_)? implode(',',$this->section_): $this->section_;
                $this->layout_code=$this->layout_;
                $this->external_url=$this->url_;
                $this->is_new_window=$this->newWindow_;
                $this->button_css_class=$this->buttonCssClass_;
                $this->status_code=$this->status_;
            }
            
            if ($this->isNewRecord) {
                $this->position = 0;
                $this->setCreateDateTime();
            } else {
                $this->setUpdateDateTime();
            }
            return true;
        }else{
            return false;
        }
    }
    
    public function generateJson(){
        $this->language_=$this->defaultLanguage;
        $this->section_=array_filter(explode(',',$this->section_code));
        foreach($this->section_ as $section){
            $this->_jsonFile=implode('_',array_filter(array(
                'menu',__CLASS__,$section, $this->language_
            )));
            
            $data=$this->readJsonFile($this->_jsonFile);
            if($this->status_code==Option::STATUS_ACTIVE){
                $data[$this->id]=array(
                    'parent'=>$this->parent_id,
                    'title'=>$this->title,
                    'url'=>$this->url,
                    'type'=>$this->type_code,
                    'external_url'=>$this->external_url,
                    'is_new_window'=>$this->is_new_window,
                    'user_access'=>explode(',',$this->user_access),
                    'position'=>$this->position,
                    'button_css_class'=>$this->button_css_class,
                );
            }elseif(isset($data[$this->id]))
                    unset($data[$this->id]);
            
            $this->createJsonFile($data, $this->_jsonFile);
        }
    }
    
    public function regenerateJson(){
        $models=$this->findAll();
        foreach($models as $data){
            $data->generateJson();
        }
        return true;
    }
    
    public function getMenu($sectionId=0){
        $this->_jsonFile=implode('_',array_filter(array(
                'menu',__CLASS__,$sectionId, Yii::app()->controller->language,
            )));
        return $this->readJsonFile($this->_jsonFile);
    }

    public function gridTitle($data, $row){
        echo $data->title;
        $this->getChildren($data->id);
    }
    
    public function adminSearch() {
        // @todo Please modify the following code to remove attributes that should not be searched.
        $t=$this->getTableAlias(false);
        $criteria = new CDbCriteria;
        
        $criteria->compare($t.'.id', $this->id_);
        if(empty($this->parent_)) $this->parent_=0;
        $criteria->compare($t.'.parent_id', $this->parent_);
        $criteria->compare($t.'.account_id', $this->accountId_);
        $criteria->compare($t.'.category_id', $this->categoryId_, true);
        $criteria->compare($t.'.type_code', $this->type_);
        $criteria->compare($t.'.section_code', $this->section_);
        $criteria->compare($t.'.status_code', $this->status_);
        $criteria->addCondition(array(
            $t.'.status_code <> '.Option::STATUS_DELETED,
        ));
        $criteria->order=$t.'.position ASC';
        return new ActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }

    public function getAllParents(){
        $data=$this->getMenu(Option::SECTION_PAGE_BREADCRUMBS);
        if(!$data) return array();
        
        function breadcrumbs(&$data, $parent){
            $menu=array();
            if(!$parent) return $menu;
            if($data[$parent]['parent'] > 0){
                $menu+=breadcrumbs($data, $data[$parent]['parent']);
                $menu[]=$data[$parent];
            }else{
                return array($data[$parent]);
            }
            return $menu;
        }
        return breadcrumbs($data, $this->parent_id);
    }
    
    public function getTypeCode(){
        return $this->type_code;
    }
    
    public function getType(){
        return $this->getTypeOption($this->type_code);
    }
    
    public function getLayoutCode(){
        return $this->layout_code;
    }
    
    public function getUrl(){
        
        switch($this->type_code){
            case Option::ARTICLE_TYPE_HOME:
                return Yii::app()->homeUrl;
                break;
            case Option::ARTICLE_TYPE_NORMAL:
            default:
                return Yii::app()->createAbsoluteUrl('site/view', array(
                    'id'=>$this->id,
                    'title'=>$this->sefUrl,
                ));
                break;
        }
    }
    
    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return Article the static model class
     */
    public static function model($className = __CLASS__) {
        return parent::model($className);
    }

}
